package c17网络编程;


import java.io.*;
import java.net.*;
import java.util.*;

/**
 * HttpClient是Apache的开源项目，Java里不能直接使用；而Android成功集成了该项目，
 * 所以可以直接使用。简单来说，它是对HttpURLConnection编程的简化增强版~
 *
 * @author 炜sama
 */
public class TestHttpURLConnection {
	//提供主方法，测试发送GET请求和POST请求
	public static void main(String args[]) throws FileNotFoundException {
		String url = "https://www.baidu.com/";
		//用这两个流来保存响应的结果到文件
		PrintStream get = new PrintStream(new File("sendGet.html"));
		PrintStream post = new PrintStream(new File("sendPost.html"));
		//发送GET请求
		String s = TestHttpURLConnection.sendGet(url, null);
		System.setOut(get);//标准输出重定向
		System.err.println(s);//控制台出现乱码的原因是控制台为GBK编码！
		//发送POST请求
		String s1 = TestHttpURLConnection.sendPost(url, "name=crazyit.org&pass=leegang");
		System.setOut(post);
		System.err.println(s1);//控制台出现乱码的原因是控制台为GBK编码！
	}

	/**
	 * 向指定URL发送GET方法的请求
	 *
	 * @param url   发送请求的URL
	 * @param param 请求参数，格式满足name1=value1&name2=value2的形式。
	 * @return URL所代表远程资源的响应
	 */
	public static String sendGet(String url, String param) {
		String result = "";
		String urlName = url + "?" + param;
		try {
			//1、创建url对象
			URL realUrl = new URL(urlName);
			//2、打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();

			//3、设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent"
					, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

			//4、建立实际的连接（上面的设置需要在此连接方法前搞定！）
			conn.connect();

			//5、使用conn对远程数据操作
			//获取所有响应头字段
			Map<String, List<String>> map = conn.getHeaderFields();
			//遍历所有的响应头字段
			for (String key : map.keySet()) {
				System.err.println(key + "--->" + map.get(key));
			}
			try (
					//定义BufferedReader输入流来读取URL的响应
					BufferedReader in = new BufferedReader(
							new InputStreamReader(conn.getInputStream(), "utf-8"))) {
				String line;
				while ((line = in.readLine()) != null) {
					result += "\n" + line;
				}
			}
		} catch (Exception e) {
			System.err.println("发送GET请求出现异常！" + e);
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 向指定URL发送POST方法的请求
	 *
	 * @param url   发送请求的URL
	 * @param param 请求参数，格式应该满足name1=value1&name2=value2的形式。
	 * @return URL所代表远程资源的响应
	 */
	public static String sendPost(String url, String param) {
		String result = "";
		try {
			//1、创建url对象
			URL realUrl = new URL(url);
			//2、打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();

			//3、设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent",
					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
			//@@发送POST请求必须设置如下两行，这是与Get方法最大的不同之处~
			conn.setDoOutput(true);
			conn.setDoInput(true);

			//4、建立实际的连接（上面的设置需要在此连接方法前搞定！）
//			conn.connect(); //因为conn.getOutputStream()会自动连接，使用这行代码可以省略！

			//5、使用conn对远程数据操作
			//@@记住要先getOutputStream再getInputStream，因为先发送请求才有响应嘛~
			try (
					//获取URLConnection对象对应的输出流
					PrintWriter out = new PrintWriter(conn.getOutputStream())) {
				//发送请求参数
				out.print(param);
				//flush输出流的缓冲
				out.flush();
			}
			try (
					//定义BufferedReader输入流来读取URL的响应
					BufferedReader in = new BufferedReader(new InputStreamReader
							(conn.getInputStream(), "utf-8"))) {
				String line;
				while ((line = in.readLine()) != null) {
					result += "\n" + line;
				}
			}
		} catch (Exception e) {
			System.err.println("发送POST请求出现异常！" + e);
			e.printStackTrace();
		}
		return result;
	}

}
